/**
* @Auther:gy
* @Date:2021/7/21 15:16
 */

package rsa

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/base64"
	"encoding/pem"
	"os"
)

// 生成RSA私钥和公钥，保存到文件中
func GenerateRSAKey(bits int) {
	//GenerateKey函数使用随机数据生成器random生成一对具有指定字位数的RSA密钥
	//Reader是一个全局、共享的密码用强随机数生成器
	privateKey, err := rsa.GenerateKey(rand.Reader, bits)
	if err != nil {
		panic(err)
	}
	//保存私钥
	//通过x509标准将得到的ras私钥序列化为ASN.1 的 DER编码字符串
	X509PrivateKey := x509.MarshalPKCS1PrivateKey(privateKey)
	//使用pem格式对x509输出的内容进行编码
	//创建文件保存私钥
	privateFile, err := os.Create("private.pem")
	if err != nil {
		panic(err)
	}
	defer privateFile.Close()
	//构建一个pem.Block结构体对象
	privateBlock := pem.Block{Type: "RSA Private Key", Bytes: X509PrivateKey}
	//将数据保存到文件
	pem.Encode(privateFile, &privateBlock)

	//保存公钥
	//获取公钥的数据
	publicKey := privateKey.PublicKey
	//X509对公钥编码
	X509PublicKey, err := x509.MarshalPKIXPublicKey(&publicKey)
	if err != nil {
		panic(err)
	}
	//pem格式编码
	//创建用于保存公钥的文件
	publicFile, err := os.Create("public.pem")
	if err != nil {
		panic(err)
	}
	defer publicFile.Close()
	//创建一个pem.Block结构体对象
	publicBlock := pem.Block{Type: "RSA Public Key", Bytes: X509PublicKey}
	//保存到文件
	pem.Encode(publicFile, &publicBlock)
}

// 公钥 加密数据
// return  进行base64加密后返回  防止乱码
// -----BEGIN RSA Public Key-----
// MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMUbToRorOYPU4TIRVlCiUz/73
// fmEN82xqkLpSQr2QgggdrLFKe1Xxi0TRAFNJAzcRBhYHtqS48gLFFPWz3C67m7BI
// zkQHC2ul7xpiW47x3iifV3zvCvaU50MhpL8YLxLQSreGKJuR1Mqi/+FzT+6jS1Am
// cV4p/N8pDsHsTPb1+QIDAQAB
// -----END RSA Public Key-----
func RSA_Encrypt(publicKey []byte, plainText []byte) (string, error) {
	//pem解码
	block, _ := pem.Decode(publicKey)
	//x509解码

	publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		return "", err
	}
	//类型断言
	pKey := publicKeyInterface.(*rsa.PublicKey)
	//对明文进行加密
	cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, pKey, plainText)
	if err != nil {
		return "", err
	}
	//返回密文
	return string(base64.StdEncoding.EncodeToString(cipherText)), nil
}

// 无需解码类似
// MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCuwwXN67x1+1tBRZZZxZ7AwAk0yYmNHbOiapCDI6pCzddxU/3lhfYOqtbMP3DirbCCw5o1wBhR96Qc8l774ZBaXZoXN+XHcCinMaHUXngV7pBbftGAY6JY1ePFLHx8wEQWlHzbFsLuGT/ovxqngZa9PWdGvuNjPO3TPaOcAHmNhQIDAQAB
func RSA_EncryptNotPem(publicKey string, plainText []byte) (string, error) {
	bs, _ := base64.StdEncoding.DecodeString(publicKey)
	publicKeyInterface, err := x509.ParsePKIXPublicKey(bs)
	if err != nil {
		return "", err
	}
	//类型断言
	pKey := publicKeyInterface.(*rsa.PublicKey)
	//对明文进行加密
	cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, pKey, plainText)
	if err != nil {
		return "", err
	}
	//返回密文
	return string(base64.StdEncoding.EncodeToString(cipherText)), nil
}

// RSA解密
func RSA_Decrypt(privateKey []byte, text string) (string, error) {
	cipherText, _ := base64.StdEncoding.DecodeString(text)
	//pem解码
	block, _ := pem.Decode(privateKey)
	//X509解码
	pKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		return "", err
	}
	//对密文进行解密
	plainText, _ := rsa.DecryptPKCS1v15(rand.Reader, pKey, cipherText)
	//返回明文
	return string(plainText), nil
}
